home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 42
/
Amiga Format AFCD42 (Issue 126, Aug 1999).iso
/
-serious-
/
comms
/
other
/
slrn
/
slrn_src
/
src
/
post.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-14
|
26KB
|
1,186 lines
/* post an article */
/* Copyright (c) 1998 John E. Davis (davis@space.mit.edu)
*
* This file is part of slrn.
*
* Slrn is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* Slrn is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with Slrn; see the file COPYING. If not, write to the Free
* Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "slrnfeat.h"
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <sys/types.h>
#include <time.h>
#include <slang.h>
#include "jdmacros.h"
#ifdef VMS
# include "vms.h"
#endif
#include "slrn.h"
#include "server.h"
#include "misc.h"
#include "post.h"
#include "group.h"
#include "art.h"
#include "uudecode.h"
#include "util.h"
#include "chmap.h"
#include "menu.h"
#if SLRN_HAS_MIME
# include "mime.h"
#endif
#define MAX_LINE_BUFLEN 2048
char *Slrn_Courtesy_CC_Message = NULL;
char *Slrn_Save_Posts_File;
char *Slrn_Save_Replies_File;
char *Slrn_Last_Message_Id;
char *Slrn_Post_Custom_Headers;
char *Slrn_Failed_Post_Filename;
int Slrn_Reject_Long_Lines = 1;
char *Slrn_Postpone_Dir;
int Slrn_Generate_Message_Id = 1;
#ifdef VMS
# define SYSTEM_OS_NAME "VMS"
#else
# ifdef __os2__
# define SYSTEM_OS_NAME "OS/2"
# else
# ifdef AMIGA
# define SYSTEM_OS_NAME "Amiga"
# else
# ifdef __unix__
# define SYSTEM_OS_NAME "UNIX"
# else
# if defined(__WIN32__) || defined(__NT__)
# define SYSTEM_OS_NAME "Windows"
# else
# define SYSTEM_OS_NAME "UNKNOWN"
# endif
# endif
# endif
# endif
#endif
static int postpone_file (char *);
#if SLRN_HAS_GEN_MSGID
static char *slrn_create_message_id (void)
{
unsigned long pid, now;
static unsigned char baseid[64];
unsigned char *b, *t, tmp[32];
char *chars32 = "0123456789abcdefghijklmnopqrstuv";
static unsigned long last_now;
if (Slrn_Generate_Message_Id == 0)
return NULL;
while (1)
{
if ((Slrn_User_Info.posting_host == NULL)
|| ((time_t) -1 == time ((time_t *)&now)))
return NULL;
if (now != last_now) break;
sleep (1);
}
last_now = now;
pid = (unsigned long) getpid ();
now -= 0x28000000;
b = baseid;
t = tmp;
while (now)
{
*t++ = chars32[now & 0x1F];
now = now >> 5;
}
while (t > tmp)
{
t--;
*b++ = *t;
}
*b++ = '.';
t = tmp;
while (pid)
{
*t++ = chars32[pid & 0x1F];
pid = pid >> 5;
}
while (t > tmp)
{
t--;
*b++ = *t;
}
*b++ = '.';
t = (unsigned char *) Slrn_User_Info.username;
if (t != NULL)
while ((*t != 0) && (b < baseid + sizeof(baseid) - 1)) *b++ = *t++;
*b = 0;
return (char *) baseid;
}
#endif
void slrn_add_signature (FILE *fp)
{
FILE *sfp;
char file[SLRN_MAX_PATH_LEN];
char buf [256];
if ((sfp = slrn_open_home_file (Slrn_User_Info.signature, "r", file, 0)) != NULL)
{
/* Apparantly some RFC suggests the -- \n. */
fputs ("\n\n-- \n", fp);
/* If signature file already has -- \n, do not add it. */
if ((NULL != fgets (buf, sizeof (buf), sfp))
&& (0 != strcmp (buf, "-- \n")))
fputs (buf, fp);
while (NULL != fgets (buf, sizeof(buf), sfp))
{
fputs (buf, fp);
}
slrn_fclose(sfp);
}
}
static int is_empty_header (char *line)
{
char *b;
if ((*line == ' ') || (*line == '\t')) return 0;
b = slrn_strchr (line, ':');
if (b == NULL) return 0;
b = slrn_skip_whitespace (b + 1);
return (*b == 0);
}
static int slrn_cc_file (char *file, char *to, char *msgid)
{
#if defined(VMS) || !SLRN_HAS_PIPING
return -1;
#else
#if defined(IBMPC_SYSTEM)
char outfile [SLRN_MAX_PATH_LEN];
#endif
FILE *pp, *fp;
char line[MAX_LINE_BUFLEN];
unsigned int cc_line = 0;
unsigned int linenum;
char buf [MAX_LINE_BUFLEN];
unsigned int nth;
char *l;
if (NULL == (fp = fopen (file, "r")))
{
slrn_error ("Unable to open %s.");
return -1;
}
/* Look for CC line */
linenum = 0;
while ((NULL != fgets (line, sizeof (line) - 1, fp)) && (*line != '\n'))
{
linenum++;
if (0 == slrn_case_strncmp ((unsigned char *)line,
(unsigned char *) "Cc: ", 4))
{
l = slrn_skip_whitespace (line + 4);
if (*l && (*l != ',')) cc_line = linenum;
break;
}
}
/* At this point, if all has gone well line contains the cc information */
if (cc_line == 0)
{
slrn_fclose (fp);
return -1;
}
#if defined(IBMPC_SYSTEM)
pp = slrn_open_tmpfile (outfile, "w");
#else
pp = slrn_popen (Slrn_SendMail_Command, "w");
#endif
if (pp == NULL)
{
slrn_fclose (fp);
return -1;
}
fputs ("To: ", pp);
/* This line consists of a comma separated list of addresses. In
* particular, "poster" will be replaced by 'to'.
*/
l = line + 4;
nth = 0;
while (0 == SLextract_list_element (l, nth, ',', buf, sizeof (buf)))
{
char *b;
/* Knock whitespace from ends of string */
b = slrn_skip_whitespace (buf);
slrn_trim_string (b);
if (nth != 0)
putc (',', pp);
if ((0 == slrn_case_strcmp ((unsigned char *)b, (unsigned char *)"poster"))
&& (to != NULL))
b = to;
fputs (b, pp);
nth++;
}
putc ('\n', pp);
rewind (fp);
linenum = 0;
#if SLRN_GEN_FROM_EMAIL_HEADER
fprintf (pp, "From: %s\n", slrn_make_from_string ());
#endif
if (msgid != NULL)
fprintf (pp, "Message-Id: <slrn%s@%s>\n",
msgid, Slrn_User_Info.posting_host);
while ((NULL != fgets (line, sizeof (line) - 1, fp)) && (*line != '\n'))
{
linenum++;
if (linenum == cc_line) continue;
if (is_empty_header (line)) continue;
if (0 == slrn_case_strncmp ((unsigned char *)line,
(unsigned char *) "To: ", 4))
continue;
/* There is some discussion of this extension to mail headers. For
* now, assume that this extension will be adopted.
*/
if (0 == slrn_case_strncmp ((unsigned char *)line,
(unsigned char *) "Newsgroups: ", 12))
{
fputs ("Posted-To: ", pp);
fputs (line + 12, pp);
}
else
fputs (line, pp);
}
# if SLRN_HAS_MIME
if (Slrn_Use_Mime) slrn_mime_add_headers (pp);
# endif
fputs ("\n", pp);
if ((NULL != Slrn_Courtesy_CC_Message) && (*Slrn_Courtesy_CC_Message))
{
slrn_insert_followup_format (Slrn_Courtesy_CC_Message, pp);
fputs ("\n", pp);
}
# if SLRN_HAS_MIME
if (Slrn_Use_Mime) fp = slrn_mime_encode (fp);
# endif
while (NULL != fgets (line, sizeof (line) - 1, fp))
{
fputs (line, pp);
}
slrn_fclose (fp);
# if defined(IBMPC_SYSTEM)
slrn_fclose (pp);
sprintf (buf, "%s %s", Slrn_SendMail_Command, outfile);
slrn_posix_system (buf, 0);
# else
slrn_pclose (pp);
# endif
return 0;
#endif /* NOT VMS */
}
/* Returns -1 upon error, 0, if ok, 1 if needs repair, 2 is warning is issued */
static int check_file_for_posting (char *file)
{
char line[MAX_LINE_BUFLEN], *the_line;
FILE *fp;
unsigned int num;
char *err;
int newsgroups_found, subject_found, only_warning;
char ch;
char *colon;
only_warning = newsgroups_found = subject_found = 0;
err = NULL;
fp = fopen (file, "r");
if (fp == NULL)
{
slrn_error ("Unable to open %s", file);
return -1;
}
the_line = line;
/* scan the header */
num = 0;
while (NULL != fgets (line, sizeof (line), fp))
{
ch = *line;
num++;
if ((ch == ' ') || (ch == '\t') || (ch == '\n'))
{
if (num == 1)
{
err = "The first line must begin with a header.";
break;
}
if (ch == '\n') break;
continue;
}
if (NULL == (c